#!/bin/bash

# Remote Deploy Script for YOLOv8 OpenVINO Project
# Updates code, compiles, and deploys new version
# Usage: ./remote-deploy.sh [host] [user] [password] [version]
# Example: ./remote-deploy.sh 192.168.10.11 asr 123456 v1.1.0

set -e

# Configuration
REMOTE_HOST="${1:-192.168.10.11}"
REMOTE_USER="${2:-asr}"
REMOTE_PASSWORD="${3:-123456}"
VERSION="${4:-v1.1.0}"
REMOTE_PATH="/home/asr/git/goyolopenvino"
DEPLOY_PATH="/opt/goyolo"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Helper functions
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_step() {
    echo -e "\n${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${YELLOW}→ $1${NC}"
    echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"
}

# Check if sshpass is installed
check_sshpass() {
    if ! command -v sshpass &> /dev/null; then
        log_error "sshpass is not installed"
        log_info "Install it with: brew install sshpass (macOS) or apt-get install sshpass (Linux)"
        exit 1
    fi
}

# SSH command wrapper
ssh_exec() {
    local cmd="$1"
    sshpass -p "$REMOTE_PASSWORD" ssh -o StrictHostKeyChecking=no \
        "${REMOTE_USER}@${REMOTE_HOST}" "$cmd"
}

# SSH command wrapper with sudo support
ssh_exec_sudo() {
    local cmd="$1"
    sshpass -p "$REMOTE_PASSWORD" ssh -o StrictHostKeyChecking=no \
        "${REMOTE_USER}@${REMOTE_HOST}" "echo '${REMOTE_PASSWORD}' | sudo -S $cmd"
}

# SCP wrapper
scp_to_remote() {
    local local_file="$1"
    local remote_path="$2"
    sshpass -p "$REMOTE_PASSWORD" scp -o StrictHostKeyChecking=no \
        "$local_file" "${REMOTE_USER}@${REMOTE_HOST}:${remote_path}"
}

# Step 1: Update code from git
update_code() {
    log_step "Step 1: Updating code from git repository"
    
    ssh_exec "cd ${REMOTE_PATH} && \
        echo 'Current branch:' && \
        git branch && \
        echo '' && \
        echo 'Pulling latest changes...' && \
        git pull origin main 2>&1 || git pull origin master 2>&1"
    
    if [ $? -eq 0 ]; then
        log_success "Code updated successfully"
    else
        log_error "Failed to update code"
        return 1
    fi
}

# Step 2: Build C++ component
build_cpp() {
    log_step "Step 2: Building C++ component"
    
    ssh_exec "cd ${REMOTE_PATH}/YOLOv8-OpenVINO-CPP-Inference && \
        echo 'Cleaning previous build...' && \
        make clean 2>&1 || true && \
        echo 'Building C++ component...' && \
        make build 2>&1"
    
    if [ $? -eq 0 ]; then
        log_success "C++ component built successfully"
    else
        log_error "Failed to build C++ component"
        return 1
    fi
}

# Step 3: Build Go component
build_go() {
    log_step "Step 3: Building Go component"
    
    ssh_exec "cd ${REMOTE_PATH}/goyolo && \
        echo 'Downloading dependencies...' && \
        go mod download && \
        go mod tidy && \
        echo 'Cleaning previous build...' && \
        make clean 2>&1 || true && \
        echo 'Building Go service...' && \
        make build 2>&1"
    
    if [ $? -eq 0 ]; then
        log_success "Go component built successfully"
    else
        log_error "Failed to build Go component"
        return 1
    fi
}

# Step 4: Run tests
run_tests() {
    log_step "Step 4: Running tests"
    
    ssh_exec "cd ${REMOTE_PATH}/goyolo && \
        echo 'Running Go tests...' && \
        go test -v ./... 2>&1"
    
    if [ $? -eq 0 ]; then
        log_success "All tests passed"
    else
        log_warning "Some tests failed (continuing with deployment)"
    fi
}

# Step 5: Stop current service
stop_service() {
    log_step "Step 5: Stopping current service"

    ssh_exec_sudo "systemctl stop goyolo 2>&1 || true" && \
    ssh_exec "echo 'Service stopped or was not running'"

    log_success "Service stopped"
}

# Step 6: Deploy new version
deploy_version() {
    log_step "Step 6: Deploying new version"

    ssh_exec "cd ${REMOTE_PATH} && \
        echo 'Creating deployment directory...' && \
        echo '${REMOTE_PASSWORD}' | sudo -S mkdir -p ${DEPLOY_PATH} && \
        echo 'Copying binaries...' && \
        echo '${REMOTE_PASSWORD}' | sudo -S cp goyolo/bin/goyolo-service ${DEPLOY_PATH}/ && \
        echo '${REMOTE_PASSWORD}' | sudo -S cp bin/detect_service ${DEPLOY_PATH}/ && \
        echo 'Setting permissions...' && \
        echo '${REMOTE_PASSWORD}' | sudo -S chmod +x ${DEPLOY_PATH}/goyolo-service && \
        echo '${REMOTE_PASSWORD}' | sudo -S chmod +x ${DEPLOY_PATH}/detect_service && \
        echo 'Creating version file...' && \
        echo '${REMOTE_PASSWORD}' | sudo -S bash -c \"echo '${VERSION}' > ${DEPLOY_PATH}/VERSION\" && \
        echo 'Deployment completed'"

    if [ $? -eq 0 ]; then
        log_success "New version deployed to ${DEPLOY_PATH}"
    else
        log_error "Failed to deploy new version"
        return 1
    fi
}

# Step 6.5: Setup systemd service
setup_systemd_service() {
    log_step "Step 6.5: Setting up systemd service"

    # Get the script directory
    local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    local service_file="${script_dir}/goyolo.service"

    if [ ! -f "$service_file" ]; then
        log_error "Service file not found: $service_file"
        return 1
    fi

    # Copy service file to remote
    sshpass -p "$REMOTE_PASSWORD" scp -o StrictHostKeyChecking=no \
        "$service_file" "${REMOTE_USER}@${REMOTE_HOST}:/tmp/goyolo.service"

    # Install service file
    ssh_exec "echo '${REMOTE_PASSWORD}' | sudo -S cp /tmp/goyolo.service /etc/systemd/system/ && \
        echo '${REMOTE_PASSWORD}' | sudo -S systemctl daemon-reload && \
        echo '${REMOTE_PASSWORD}' | sudo -S systemctl enable goyolo && \
        echo 'Systemd service configured'"

    if [ $? -eq 0 ]; then
        log_success "Systemd service configured"
    else
        log_error "Failed to configure systemd service"
        return 1
    fi
}

# Step 7: Start service
start_service() {
    log_step "Step 7: Starting service"

    ssh_exec "echo '${REMOTE_PASSWORD}' | sudo -S systemctl start goyolo && \
        sleep 2 && \
        echo '${REMOTE_PASSWORD}' | sudo -S systemctl status goyolo"

    if [ $? -eq 0 ]; then
        log_success "Service started successfully"
    else
        log_error "Failed to start service"
        return 1
    fi
}

# Step 8: Verify deployment
verify_deployment() {
    log_step "Step 8: Verifying deployment"

    ssh_exec "echo 'Checking service status...' && \
        echo '${REMOTE_PASSWORD}' | sudo -S systemctl status goyolo && \
        echo '' && \
        echo 'Checking deployed binaries...' && \
        ls -lh ${DEPLOY_PATH}/ && \
        echo '' && \
        echo 'Checking version...' && \
        cat ${DEPLOY_PATH}/VERSION 2>/dev/null || echo 'Version file not found'"

    log_success "Deployment verification completed"
}

# Main execution
main() {
    log_info "Remote Deploy Script Started"
    log_info "Target: ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}"
    log_info "Version: ${VERSION}"
    log_info "Deploy Path: ${DEPLOY_PATH}"
    echo ""
    
    # Check prerequisites
    check_sshpass
    
    # Test SSH connection
    log_info "Testing SSH connection..."
    if ssh_exec "echo 'SSH connection successful'" > /dev/null 2>&1; then
        log_success "SSH connection established"
    else
        log_error "Failed to connect to remote host"
        exit 1
    fi
    echo ""
    
    # Execute deployment steps
    update_code || exit 1
    build_cpp || exit 1
    build_go || exit 1
    run_tests || true  # Don't exit on test failure
    stop_service || true  # Don't exit if service wasn't running
    deploy_version || exit 1
    setup_systemd_service || exit 1
    start_service || exit 1
    verify_deployment
    
    echo ""
    log_success "Deployment completed successfully!"
    echo ""
    echo -e "${GREEN}Summary:${NC}"
    echo "  Version: ${VERSION}"
    echo "  Host: ${REMOTE_HOST}"
    echo "  Deploy Path: ${DEPLOY_PATH}"
    echo "  Service: goyolo"
    echo ""
    echo -e "${YELLOW}Next steps:${NC}"
    echo "  1. Verify service is running: curl http://${REMOTE_HOST}:8080/health"
    echo "  2. Check logs: ssh ${REMOTE_USER}@${REMOTE_HOST} 'sudo journalctl -u goyolo -f'"
    echo "  3. Test API: Open api-test.html in browser"
}

# Show usage
show_usage() {
    cat << EOF
${GREEN}=== Remote Deploy Script ===${NC}

Usage: $0 [host] [user] [password] [version]

Arguments:
  host      Remote host IP (default: 192.168.10.11)
  user      SSH username (default: asr)
  password  SSH password (default: 123456)
  version   Version tag (default: v1.1.0)

Examples:
  # Default deployment
  $0

  # Custom host and version
  $0 192.168.10.11 asr 123456 v1.2.0

  # Custom everything
  $0 10.0.0.5 deploy mypass v2.0.0

Workflow:
  1. Update code from git
  2. Build C++ component
  3. Build Go component
  4. Run tests
  5. Stop current service
  6. Deploy new version
  7. Start service
  8. Verify deployment

EOF
}

# Main entry point
if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
    show_usage
    exit 0
fi

main "$@"

